#include "Tore.h"
#include "stdafx.h"

Tore::Tore(): Objet(){};
Tore::Tore(float r1, float R1, Point p):r(r1),R(R1),centre(p){}

Tore::~Tore(){}

bool Tore::intersection(Rayon rayon) {
	Vecteur directionRayon = rayon.getDirection();
	Point origineRayon = rayon.getOrigine();

	float xC = centre.getX(), yC = centre.getY(), zC = centre.getZ();
	float xO = origineRayon.getX()-xC, yO = origineRayon.getY()-yC, zO = origineRayon.getZ()-zC;
	float xD = directionRayon.getX(), yD = directionRayon.getY(), zD = directionRayon.getZ();

	float xO2 = xO*xO, yO2 = yO*yO, zO2 = zO*zO;
	float xD2 = xD*xD, yD2 = yD*yD, zD2 = zD*zD;

	float RR2 = R*R;
	float rr2 = r*r;

	float tmpD2 = xD2 + yD2 + zD2;
	float tmpO2 = xO2 + yO2 + zO2 + RR2 - rr2;
	float tmpDO = xD *xO + yD *yO + zD* zO;

	float coeffA = tmpD2*tmpD2;
	float coeffB = 4.0f* tmpD2 * tmpDO;
	float coeffC = 2.0f * tmpD2 * tmpO2 + 4.0f * tmpDO * tmpDO - 4.0f * RR2 * (xD2 + zD2);
	float coeffD = 4.0f * tmpDO * tmpO2 - 8.0f * RR2 *(xD * xO + zD * zO);
	float coeffE = tmpO2 * tmpO2 - 4.0f * RR2 * (xO2 + zO2);

	double roots[4];
    int nbRoots=0;
	nbRoots = Equation::SolveQuartic(coeffA, coeffB, coeffC, coeffD, coeffE, roots);
	float t= MAXFLOAT;
	for (int i=0 ; i<nbRoots ; i++) {
		if (roots[i] >0 && roots[i]<t)  {
			t= (float) (roots[i]);
		}
	}

	if (t==MAXFLOAT || t<0) {
		return false;
	}

	
	Point m = Point(origineRayon.getX()+xD*t, origineRayon.getY()+yD*t, origineRayon.getZ()+zD*t,1);
	inter.setPoint(m);

	float k = (m.getX()-xC) * (m.getX()-xC) + (m.getY()-yC) * (m.getY()-yC) +( m.getZ()-zC) * (m.getZ()-zC) + RR2 - rr2;
	Vecteur normal (4 * (m.getX()-xC) * k - 8 * RR2 * (m.getX()-xC),
					4 * (m.getY()-yC) * k,
					4 * (m.getZ()-zC) * k - 8 * RR2 * (m.getZ()-zC) );
	normal.normalize();
	inter.setNormale(normal);
	inter.setT(t);
	return true;
}

BoiteEnglobante Tore::getBoite()
{
	BoiteEnglobante b;
    
	b.corner1.setX(centre.getX() - R);
	b.corner1.setY(centre.getY() - R);
	b.corner1.setZ(centre.getZ() - R);

	b.corner2.setX(centre.getX() + R);
	b.corner2.setY(centre.getY() + R);
	b.corner2.setZ(centre.getZ() + R);	
    
	return b;
}

bool Tore::aBoite()
{
	return true;
}

